package com.fm.controller;

import com.fm.entity.AbstractMyBatisEntity;
import com.fm.service.MBaseService;
import com.fm.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.ParameterizedType;
import java.util.Map;
import java.util.Optional;

/**
 * Created by Administrator on 2018/7/30 0030.
 */
public abstract class MBaseController<T extends AbstractMyBatisEntity, S extends MBaseService> {
    @Autowired
    protected S baseService;
    private static final String PAGE_SIZE = "10";
    protected Class<T> entityClass;

    @SuppressWarnings("unchecked")
    public MBaseController(){
        if (this.entityClass == null) {
            this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                    .getActualTypeArguments()[0];
        }
    }
    /**
     * 用于在新增时初始化，需要传入参数op=add
     * @param t
     */
    public  void beforeAdd(T t,HttpServletRequest request){

    }
    /**
     * 编辑时，对象检索出来之后在导向到编辑页面前进行二次包装处理
     * @param t
     */
    public void afterEditOpen(T t,HttpServletRequest request){
    }

    /**
     * 更新前做的事
     * @param t
     * @param request
     */
    public void beforeUpdate(T t,HttpServletRequest request){

    }
    public void afterUpdate(T t,HttpServletRequest request){

    }
    /**
     * 新增插入记录前做的事
     * @param t
     * @param request
     */
    public void beforeInsert(T t,HttpServletRequest request){

    }
    public void afterInsert(T t,HttpServletRequest request){

    }
    public void afterSave(T t,HttpServletRequest request){

    }
    public void beforeDelete(Integer id,HttpServletRequest request){

    }
    public void afterDelete(Integer id,HttpServletRequest request){

    }
    public abstract T beforeList(Map t);

    public void afterList(Page<T> page){};

    public void afterSelectOne(T t){};

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "insert", method = RequestMethod.POST)
    public R insert(@RequestBody T t, HttpServletRequest request){
        beforeInsert(t,request);
        this.baseService.insert(t);
        afterInsert(t,request);
        afterSave(t, request);
        return R.ok();
    }

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public R update(@RequestBody T t, HttpServletRequest request){
        beforeUpdate(t,request);
        this.baseService.update(t);
        afterUpdate(t,request);
        afterSave(t, request);
        return R.ok();
    }

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public R delete(Integer id, HttpServletRequest request){
        beforeDelete(id,request);
        this.baseService.deleteById(id);
        afterDelete(id,request);
        return R.ok();
    }

    @RequestMapping(value = "list")
    @ResponseBody
    public R list(@RequestParam Map<String, Object> params, HttpServletRequest request){
        try{
            String pageNum = (String) params.get("currentPage");
            if (pageNum == null) pageNum = "1";
            String pageSize = (String) params.get("pageSize");
            if (pageSize == null) pageSize = PAGE_SIZE;
            T t = beforeList(params);
            String orderBy = t.getOrderBy();
            if (params.get("orderBy")!=null){
                orderBy = (String) params.get("orderBy");
            }
            Page<T> page = baseService.queryPage(t, Integer.parseInt(pageNum)-1, Integer.parseInt(pageSize), orderBy);
            afterList(page);
            return R.ok().put("page", page);
        }catch(DataAccessException da){
            throw new RuntimeException(da.getRootCause().getMessage());
        }
    }

    @RequestMapping(value = "selectOne")
    @ResponseBody
    public R selectOne(Integer id, HttpServletRequest request){
        try{
            Optional<T> entity =  baseService.selectOneByExample(id);
            T t = entity.get();
            afterSelectOne(t);
            return R.ok().put("entity", t);
        }catch(DataAccessException da){
            throw new RuntimeException(da.getRootCause().getMessage());
        }
    }
}
